package lol.clann.minecraft.springboot.api.bukkit.utils;

import lol.clann.minecraft.springboot.api.model.Slot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;

import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

/**
 *
 * @author pyz
 * @date 2019/5/15 11:06 PM
 */
public interface InventoryUtils {
    /**
     * bukkitInventory转换成NMSInventory
     * @param inventory
     * @param <T>
     * @return
     */
    <T> T toNMS(Inventory inventory);

    /**
     * 标记背包被修改了,需要保存
     *
     * @param inventory
     */
    void markDirty(Inventory inventory);

    /**
     * NMSInventory转换成bukkitInventory
     * @param inventoryView
     * @param <T>
     * @return
     */
    <T> T toNMS(InventoryView inventoryView);

    /**
     * 判断一个TileEntity是不是容器
     *
     * @param nmsTileEntity
     * @param <T>
     * @return
     */
    <T> boolean isNMSInventory(T nmsTileEntity);

    /**
     * 获取nmsInventory的大小
     * @param nmsInventory
     * @return
     */
    int getSize(Object nmsInventory);

    /**
     * 获取NMSInventory中指定位置的物品
     * @param nmsInventory
     * @param index
     * @return
     */
    ItemStack getItem(Object nmsInventory, int index);

    /**
     * 设置nmsInventory指定位置的物品
     *
     * @param nmsInventory
     * @param index
     * @param itemStack
     */
    void setItem(Object nmsInventory, int index, ItemStack itemStack);

    /**
     * 返回所有空格子的index
     * @param inventory
     * @return
     */
    List<Integer> emptySlots(Inventory inventory);

    /**
     * 获取背包中所有物品
     * key:index
     * value:ItemStack
     * @param inventory
     * @return
     */
    Map<Integer, ItemStack> getContent(Inventory inventory);

    /**
     * 计算剩余空间可以装多少个指定物品
     *
     * @param inventory
     * @param itemStack
     * @return
     */
    int capabilityFor(Inventory inventory, ItemStack itemStack);

    /**
     * 对指定物品进行计数
     *
     * @param inventory
     * @return
     */
    int count(Inventory inventory, ItemStack itemStack);

    /**
     * 迭代所有格子
     * 包含空格子
     *
     * @param inventory
     * @return
     */
    Iterable<Slot> allSlots(Inventory inventory);

    /**
     * 迭代所有空格子
     *
     * @param inventory
     * @return
     */
    Iterable<Slot> allEmptySlots(Inventory inventory);

    /**
     * 迭代所有格子
     * 不包含空格子
     *
     * @param inventory
     * @return
     */
    Iterable<Slot> allItems(Inventory inventory);

    /**
     * 迭代相同物品
     *
     * @param inventory
     * @param requireItemStack
     * @return
     */
    Iterable<Slot> allItems(Inventory inventory, ItemStack requireItemStack);

    /**
     * 迭代满足条件的物品
     *
     * @param inventory
     * @param filter
     * @return
     */
    Iterable<Slot> allItems(Inventory inventory, Predicate<ItemStack> filter);


    /**
     * 提取指定数量的物品
     * 数量不足会抛异常
     * -1表示全部提取
     *
     * @param inventory
     * @return
     */
    Map<Integer, ItemStack> pull(Inventory inventory, ItemStack itemStack, int count);

    /**
     * 放指定数量的物品到玩家背包
     *
     * @param inventory
     * @param itemStack
     * @param count
     * @return 没放进去的数量
     */
    int put(Inventory inventory, ItemStack itemStack, int count);
}
